pub extern crate wasm_bindgen;
pub extern crate web_sys;
extern crate xloop_types as types;

pub mod app;
pub mod error;
pub mod win;

pub mod prelude {}

#[derive(Debug)]
pub struct Application;
impl types::App for Application {
	type Error = error::Error;
	type Ref<'a> = app::AppRef;
	fn with(fun: impl FnOnce(Self::Ref<'_>)) {
		app::with_app(fun);
	}
	fn run(rep: impl types::AppRep<Self>) -> Result<(), Self::Error> {
		app::init_app(rep);
		app::AppHandle.run();
		Ok(())
	}
}
impl types::Log for Application {
	fn log(level: types::LevelFilter) {
		let level = match level {
			types::LevelFilter::Off => log::LevelFilter::Off,
			types::LevelFilter::Error => log::LevelFilter::Error,
			types::LevelFilter::Warn => log::LevelFilter::Warn,
			types::LevelFilter::Info => log::LevelFilter::Info,
			types::LevelFilter::Debug => log::LevelFilter::Debug,
			types::LevelFilter::Trace => log::LevelFilter::Trace,
		};
		console_log::init_with_level(level.to_level().unwrap_or(log::Level::Info)).ok();
	}
}
impl types::Fs for Application {
	fn read(_path: impl AsRef<std::path::Path>) -> impl std::future::Future<Output = std::io::Result<Vec<u8>>> {
		std::future::ready(Err(std::io::Error::new(std::io::ErrorKind::Other, "not implemented")))
	}
}

#[derive(Debug)]
pub struct Window;

impl types::Win for Window {
	type Error = error::Error;
	type WinRaw = win::WinRaw;
	type WinRef<'a> = win::WinRef<'a>;
	type WinHandle = win::WinHandle;
	type Mouse<'a> = win::WinMouse<'a>;
	type Wheel<'a> = win::WinWheel<'a>;
	type Keyboard<'a> = win::WinKeyboard<'a>;
	type Touch<'a> = win::WinTouch<'a>;
	type Ime<'a> = &'a types::Ime;
	type Attr = types::XwinAttr;
	fn win(key: impl AsRef<str>, _: Self::Attr, rep: impl types::WinRep<Self> + 'static) -> Result<Self::WinHandle, Self::Error> {
		win::new_window(key, rep).ok_or(error::Error)
	}
}
